package one.stand.controller.supplier;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.jmp.api.dto.GoodsSaveRequest;
import com.jmp.api.dto.*;
import com.jmp.autocofiguration.web.interceptor.SecurityAuthCheck;
import com.jmp.base.TemplateApi;
import com.jmp.base.dto.GoodsMainPushRequest;
import com.jmp.base.dto.*;
import com.jmp.feign.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import one.stand.advice.ResultEnum;
import one.stand.dto.Company2Dto;
import one.stand.dto.ConvertUtils;
import one.stand.dto.GoodsDetailDto;
import one.stand.dto.PageResponse2;
import one.stand.enums.LoginEnum;
import one.stand.mapper.GoodSpecMapperExt;
import one.stand.mapper.GoodsApiCrmAppMapper;
import one.stand.model.*;
import one.stand.service.*;
import one.stand.util.*;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;

/**
 * @author cjr
 */
@Api(description = "商品管理")
@RestController
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    private GoodsFeign goodsFeign;
    @Autowired
    private TemplateFeign templateFeign;
    @Autowired
    private AccountFeign accountFeign;
    @Autowired
    private GoodsTypeFeign goodsTypeFeign;
    @Autowired
    private CompanyFeign companyFeign;
    @Autowired
    private SeeRecordFeign seeRecordFeign;
    @Autowired
    private RecordFeign recordFeign;

    @Autowired
    private CompanyBaseService companyBaseService;
    @Autowired
    private GoodsBaseService goodsBaseService;
    @Autowired
    private GoodsPhotoService goodsPhotoService;
    @Autowired
    private GoodsTypeService goodsTypeService;
    @Autowired
    private BusinessCardBaseService businessCardBaseService;
    @Autowired
    private GoodSpecMapperExt goodSpecMapperExt;
    @Autowired
    private CompanyShowroomService companyShowroomService;
    @Autowired
    private RecordPublicService recordPublicService;

    @Autowired
    private GoodsApiCrmAppMapper goodsApiCrmAppMapper;

    @ApiOperation(value = "1商品列表")
    @ApiImplicitParams({})
    @GetMapping("/list")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsListResponse> getGoodsTypeInfo(@RequestAttribute GoodsListRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        String nameLike = SqlUtil.like(request.getKeyword());
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<Goods> goodsModelList = goodsApiCrmAppMapper.selectGoodsInfo(
                request.getTypeId()
                , optUser.getCompanyId()
                , false
                , null
                , nameLike
        );

        PageResponse2<GoodsListResponse.Goods> goodsPageResponse2 = ConvertUtils.page2(goodsModelList, goodsModel -> {
            GoodsType goodsType = goodsTypeService.get(goodsModel.getGoodstypeId());
            GoodSpecModel specModel = new GoodSpecModel();
            specModel.setGoodsId(goodsModel.getGoodsId());
            specModel.setIsDel(0);
            List<GoodSpecModel> specModelList = goodSpecMapperExt.getSpec(specModel);
            return GoodsListResponse.Goods.builder()
                    .goodsId(goodsModel.getGoodsId())
                    .goodsName(goodsModel.getGoodsName())
                    .price(goodsModel.getPrice())
                    .goodPhoto(OneStringUtils.photoResize(goodsPhotoService.getPath(goodsModel.getGoodsId())))
                    .typeName(Objects.nonNull(goodsType) ? goodsType.getGroupName() : null)
                    .mainPush(goodsModel.getMainPush())
                    .editFlag(BooleanUtils.toInteger(OneListUtil.isEmpty(specModelList) || specModelList.size() <= 1))
                    .build();
        });

        GoodsListResponse response = GoodsListResponse.builder()
                .goodsPage(goodsPageResponse2)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "2分类列表")
    @GetMapping("/list/type")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsListTypeResponse> listType() {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        // 获取一级分类
        Integer parentId = GoodsTypeService.PARENT_ID;
        List<GoodsType> list = goodsApiCrmAppMapper.selectTypesChild(parentId, optUser.getCompanyId(), false, false);
        List<GoodsListTypeResponse.Type> types = ConvertUtils.list(list, type -> GoodsListTypeResponse.Type.builder()
                .id(type.getGoodstypeId())
                .name(type.getGroupName())
                .build());

        // 填充二级分类
        for (GoodsListTypeResponse.Type type : types) {
            List<GoodsType> children = goodsApiCrmAppMapper.selectTypesChild(type.getId(), optUser.getCompanyId(), false, false);
            type.setChildren(ConvertUtils.list(children, child -> GoodsListTypeResponse.Type.builder()
                    .id(child.getGoodstypeId())
                    .name(child.getName())
                    .groupName(child.getGroupName())
                    .build()));
        }
        GoodsListTypeResponse response = GoodsListTypeResponse.builder()
                .types(types)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "3删除商品")
    @PostMapping("/remove")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel delGoodsInfo(@RequestAttribute GoodsRemoveRequest request) {
        ResultModel resultModel = goodsFeign.remove(GoodsRemoveDto.builder().goodsId(request.getGoodsId()).build());
        AssertUtil.isTrue(resultModel);
        return ResultModel.success();
    }

    @ApiOperation(value = "3主推/取消主推")
    @PostMapping("/main/push")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel mainPush(@RequestAttribute com.jmp.api.dto.GoodsMainPushRequest request) {
        ResultModel resultModel = goodsFeign.mainPush(GoodsMainPushRequest.builder()
                .goodsId(request.getGoodsId())
                .mainPush(BooleanUtils.toBoolean(request.getMainPush()))
                .build());
        AssertUtil.isTrue(resultModel);
        return ResultModel.success();
    }

    @ApiOperation(value = "3商品分享")
    @GetMapping("/share")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsShareResponse> share(@RequestAttribute GoodsShareRequest request) {
        Goods goodsModel = goodsBaseService.get(request.getGoodsId());
        AssertUtil.nonNull(goodsModel, "商品不存在");
        AssertUtil.isTrue(goodsModel.getIsDel() == 0, "商品已下架");

        Integer cardId = request.getCardId();
        Integer companyId;
        if (Objects.isNull(cardId)) {//企业名片
            ResultModel<CompanyCardResponse> cardResponseResultModel = companyFeign.card(CompanyCardRequest.builder().companyId(goodsModel.getCompanyId()).build());
            companyId = goodsModel.getCompanyId();
            cardId = ConvertUtils.result(cardResponseResultModel, CompanyCardResponse::getCardId);
        } else {
            BusinessCard card = businessCardBaseService.getCustomer(cardId);
            companyId = card.getCompanyId();
        }

        TemplateGet2Request getRequest = TemplateGet2Request.builder()
                .templateType(TemplateApi.Type.ID_CRM_APP_GOODS)
                .cardId(cardId)
                .goodsId(request.getGoodsId())
                .build();
        ResultModel<TemplateGetResponse> getResponseResultModel = templateFeign.get2(getRequest);
        AssertUtil.isTrue(getResponseResultModel);
        String cardUrl = getResponseResultModel.getData().getImageUrl();

        AccountCompanyIdRequest accountCompanyIdRequest = AccountCompanyIdRequest.builder()
                .companyId(companyId)
                .loginEnum(LoginEnum.USER)
                .build();
        ResultModel<AccountResponse> accountResponseResultModel = accountFeign.getCompanyIdDefaultIfNull(accountCompanyIdRequest);
        String wechatId = accountResponseResultModel.isSuccess() ? accountResponseResultModel.getData().getWechatId() : null;

        GoodsShareResponse response = GoodsShareResponse.builder()
                .cardUrl(cardUrl)
                .wechatId(wechatId)
                .wechatTitle(goodsModel.getGoodsName())
                .wechatImg(goodsPhotoService.getPath(request.getGoodsId()))
                .path("/pages/prodDetail/main?goodId=" + request.getGoodsId() + "&cardId=" + cardId + "&companyId=" + companyId)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "4商品分类:添加/修改")
    @PostMapping("/type/save")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel typeSave(@RequestAttribute GoodsTypeSaveRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        goodsTypeService.save(optUser.getCompanyId()
                , request.getName()
                , request.getParentId()
                , request.getTypeId()
                , request.getIsShow()
                , null
        );
        return ResultModel.success();
    }

    @ApiOperation(value = "4商品分类:删除")
    @PostMapping("/type/remove")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel typeRemove(@RequestAttribute GoodsTypeRemoveRequest request) {

        ResultModel resultModel = goodsTypeFeign.delete(com.jmp.base.dto.GoodsTypeDeleteRequest.builder().goodsTypeId(request.getTypeId()).build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation(value = "4商品分类:上移/下移")
    @PostMapping("/type/move")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel moveGoodsType(@RequestAttribute GoodsTypeMoveRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        goodsTypeService.updateSort(request.getTypeId(), request.getType(), optUser.getCompanyId());

        return ResultModel.success();
    }

    @ApiOperation(value = "5编辑商品:保存")
    @PostMapping("/save")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel save(@RequestAttribute GoodsSaveRequest request) {
        final Integer userCompanyId = RequestContextHolder.getRequestContext().getUser().getCompanyId();

        List<com.jmp.base.dto.GoodsSaveRequest.Spec> specs = Lists.newArrayList();
        String specName = "默认";
        if (OneListUtil.isEmpty(request.getGoodSpecRequestList())) {
            GoodsSaveRequest.Spec spec = GoodsSaveRequest.Spec.builder()
                    .specAttribute(specName)
                    .price(BigDecimal.ZERO)
                    .specNum(0)
                    .build();
            request.getGoodSpecRequestList().add(spec);
        }
        if (Objects.nonNull(request.getGoodsId())) {
            GoodSpecModel specModel = new GoodSpecModel();
            specModel.setGoodsId(request.getGoodsId());
            specModel.setIsDel(0);
            List<GoodSpecModel> specModelList = goodSpecMapperExt.getSpec(specModel);
            AssertUtil.isTrue(OneListUtil.isEmpty(specModelList) || specModelList.size() <= 1, ResultEnum.PARAM_CHECK, "请到电脑端编辑本商品");
            if (OneListUtil.isNotEmpty(specModelList)) {
                specName = specModelList.get(0).getSpecName();
            }
        }
        com.jmp.base.dto.GoodsSaveRequest.Spec spec = com.jmp.base.dto.GoodsSaveRequest.Spec.builder()
                .specName(specName)
                .goodSpecModelList(ConvertUtils.list(request.getGoodSpecRequestList(), getFunction()))
                .build();
        specs.add(spec);

        String detail = goodsBaseService.getDetails(GoodsDetailDto.builder()
                .goodsDetailsMemo(request.getGoodsDetailsMemo())
                .goodsDetailsImgs(request.getGoodsDetailsImgs())
                .build());

        com.jmp.base.dto.GoodsSaveRequest saveRequest = com.jmp.base.dto.GoodsSaveRequest.builder()
                .goodsId(request.getGoodsId())
                .goodsName(request.getGoodsName())
                .goodstypeId(request.getGoodstypeId())
                .goodsDetails(detail)
                .isPayment(request.getIspayment())
                .showPrice(BooleanUtils.toInteger(request.getIspayment() == 1))
                .coverImg(null)
                .goodPhoto(request.getGoodsPhotos())
                .companyId(userCompanyId)
                .fromApp(Objects.isNull(request.getGoodsId()) ? 1 : null)
                .specList(specs)
                .build();
        return goodsFeign.save2(saveRequest);
    }

    @ApiOperation(value = "5编辑商品:信息")
    @GetMapping("/info")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsInfoResponse> info(@RequestAttribute GoodsInfoRequest request) {
        AssertUtil.nonNull(request, ResultEnum.PARAM_CHECK);

        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        Goods goodsModel = goodsBaseService.get(request.getGoodsId());
        AssertUtil.nonNull(goodsModel, "商品不存在");
        AssertUtil.isTrue(goodsModel.getIsDel() == 0, "商品已下架");
        AssertUtil.isTrue(goodsModel.getCompanyId().equals(optUser.getCompanyId()), ResultEnum.PARAM_CHECK);

        List<String> photos = goodsPhotoService.getListPath(request.getGoodsId());
        String photosArr = StringUtils.join(photos, OneConstant.arraySymbol);

        GoodsType goodsType = goodsTypeService.get(goodsModel.getGoodstypeId());

        GoodSpecModel specModel = new GoodSpecModel();
        specModel.setGoodsId(request.getGoodsId());
        specModel.setIsDel(0);
        List<GoodSpecModel> specModelList = goodSpecMapperExt.getSpec(specModel);
        AssertUtil.isTrue(OneListUtil.isEmpty(specModelList) || specModelList.size() <= 1, ResultEnum.PARAM_CHECK, "请到电脑端编辑本商品");
        List<GoodsInfoResponse.Spec> goodSpecModelList = null;
        if (OneListUtil.isNotEmpty(specModelList) && specModelList.size() == 1) {
            goodSpecModelList = ConvertUtils.list(specModelList.get(0).getGoodSpecModelList(), goodSpecModel -> GoodsInfoResponse.Spec.builder()
                    .specAttribute(goodSpecModel.getSpecAttribute())
                    .price(MoneyUtil.getMoney(goodSpecModel.getPrice()))
                    .specNum(goodSpecModel.getSpecNum())
                    .build());
        }

        //解析详情
        GoodsDetailDto goodsDetailDto = goodsBaseService.getDetails(goodsModel.getGoodsDetails());

        GoodsInfoResponse response = GoodsInfoResponse.builder()
                //商品信息
                .goodsId(goodsModel.getGoodsId())
                .goodstypeId(goodsModel.getGoodstypeId())
                .goodstypeName(goodsType.getGroupName())
                .goodsName(goodsModel.getGoodsName())
                .goodsPhotos(photosArr)
                .goodsDetailsEditFlag(BooleanUtils.toInteger(goodsDetailDto.isGoodsDetailsEditFlag()))
                .goodsDetailsMemo(goodsDetailDto.getGoodsDetailsMemo())
                .goodsDetailsImgs(goodsDetailDto.getGoodsDetailsImgs())
                .ispayment(goodsModel.getIsPayment())
                .goodSpecModelList(goodSpecModelList)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "6商品预览|商品详情")
    @GetMapping("/detail")
    public ResultModel<GoodsDetailResponse> getGoodsInfo(@RequestAttribute GoodsDetailRequest request) {
        AssertUtil.nonNull(request, ResultEnum.PARAM_CHECK);

        Goods goodsModel = goodsBaseService.get(request.getGoodsId());
        AssertUtil.nonNull(goodsModel, "商品不存在");
        AssertUtil.isTrue(goodsModel.getIsDel() == 0, "商品已下架");

        List<String> photos = goodsPhotoService.getListPath(request.getGoodsId());
        String photosArr = StringUtils.join(photos, OneConstant.arraySymbol);

        GoodSpecModel specModel = new GoodSpecModel();
        specModel.setGoodsId(request.getGoodsId());
        specModel.setIsDel(0);
        List<GoodSpecModel> specModelList = goodSpecMapperExt.getSpec(specModel);
        List<GoodsDetailResponse.Spec> goodSpecModelList = ConvertUtils.list(specModelList, goodSpecModel -> GoodsDetailResponse.Spec.builder()
                .specId(goodSpecModel.getSpecId())
                .specName(goodSpecModel.getSpecName())
                .goodSpecModelList(ConvertUtils.list(goodSpecModel.getGoodSpecModelList(), spec -> GoodsDetailResponse.Spec.builder()
                        .specId(spec.getSpecId())
                        .specName(StringUtils.isNoneBlank(spec.getSpecAttribute()) ? spec.getSpecAttribute() : spec.getSpecName())
                        .specNum(spec.getSpecNum())
                        .price(MoneyUtil.getMoney(spec.getPrice()))
                        .build()))
                .build());

        RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        final boolean isLogin = Objects.nonNull(optUser);
        boolean isCollect = isLogin && recordPublicService.isCollection(optUser.getUserId(), RecordPublicService.ITEMTYPE_GOODS, request.getGoodsId());

        //没有指定名片时取企业名片
        Integer cardId = request.getCardId();
        if (Objects.isNull(cardId)) {
            ResultModel<CompanyCardResponse> cardResponseResultModel = companyFeign.card(CompanyCardRequest.builder().companyId(goodsModel.getCompanyId()).build());
            cardId = ConvertUtils.result(cardResponseResultModel, CompanyCardResponse::getCardId);
        }
        String kfTel = StringUtils.EMPTY;
        String kfChatId = StringUtils.EMPTY;
        String kfChatImg = StringUtils.EMPTY;
        if (Objects.nonNull(cardId)) {
            BusinessCard businessCard = businessCardBaseService.getCustomer(cardId);
            if (Objects.nonNull(businessCard)) {
                kfChatId = String.valueOf(businessCard.getUserId());
                kfChatImg = businessCard.getLogo();
                kfTel = businessCard.getPhone();
            }
        }

        //企业
        Company2Dto company = companyBaseService.get2(goodsModel.getCompanyId());
        final boolean hasZkgx = companyBaseService.hasZkgx(goodsModel.getCompanyId());
        CompanyShowroom companyShowroom = companyShowroomService.getByCompanyId(company.getCompanyId());

        final boolean editAble = RequestContextHolder.getRequestContext().isSameCompany(goodsModel.getCompanyId());//本企业商品
        if (isLogin && !editAble) {//添加查看记录
            SeeRecordGoodsRequest recordGoodsRequest = SeeRecordGoodsRequest.builder()
                    .userId(optUser.getUserId())
                    .cardId(cardId)
                    .companyId(goodsModel.getCompanyId())
                    .itemId(request.getGoodsId())
                    .build();
            seeRecordFeign.goods(recordGoodsRequest);
        }

        String info = StringUtils.EMPTY;
        if (editAble && RequestContextHolder.getRequestContext().isBoss()) {
            info = "<p>" + goodsModel.getWholesaleInfo() + "</p>";
        }

        GoodsDetailResponse response = GoodsDetailResponse.builder()
                //商品信息
                .goodsId(goodsModel.getGoodsId())
                .goodsName(goodsModel.getGoodsName())
                .goodsPhotos(photosArr)
                .videoUrl(goodsModel.getVideoUrl())
                .goodSpecModelList(goodSpecModelList)
                .goodsDetails(info + goodsModel.getGoodsDetails())
                .ispayment(goodsModel.getIsPayment())
                .price(goodsModel.getShowPrice() == 1 ? goodsModel.getPrice().toString() : "购买咨询客服")//是否显示价格 0不显示1显示
                .mainPush(goodsModel.getMainPush())
                .editFlag(BooleanUtils.toInteger(OneListUtil.isEmpty(specModelList) || specModelList.size() <= 1))
                .editAble(BooleanUtils.toInteger(editAble))

                //企业
                .companyId(goodsModel.getCompanyId())
                .companyName(company.getCompanyName())
                .companyLogo(company.getCompanyLogo())
                .companyLevel(company.countCompanyLevelView())
                .hasZkgx(BooleanUtils.toInteger(hasZkgx))
                .companyAddrArea(company.getAddrArea())
                .companyAddrStreet(company.getAddrStreet())
                .companyAddrNo(company.getAddrNo())
                .companyVrUrl(Objects.nonNull(companyShowroom) ? companyShowroom.getVrUrl() : null)

                //客服|代理
                .goodsSelected(0)
                .collectFlag(BooleanUtils.toInteger(isCollect))
                .qjVrUrl(goodsModel.getQjVrUrl())
                .kfTel(isLogin ? kfTel : StringUtils.EMPTY)
                .kfChatId(kfChatId)
                .kfImg(kfChatImg)
                .cardId(cardId)

                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "7商品收藏/取消收藏")
    @PostMapping("/collect")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel collect(@RequestAttribute GoodsCollectRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        ResultModel<RecordCollectionVo> resultModel = recordFeign.collection(RecordCollectionDto.builder()
                .userId(optUser.getUserId())
                .itemType(RecordPublicService.ITEMTYPE_GOODS)
                .itemId(request.getGoodsId())
                .build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    private Function<GoodsSaveRequest.Spec, com.jmp.base.dto.GoodsSaveRequest.Spec> getFunction() {
        return spec -> {
            return com.jmp.base.dto.GoodsSaveRequest.Spec.builder()
                    .specAttribute(spec.getSpecAttribute())
                    .price(spec.getPrice())
                    .specNum(spec.getSpecNum())
                    .build();
        };
    }
}
